<?php

namespace app\admin\controller\insurance;

use app\admin\model\InsurancePolicy;
use app\admin\model\InsuranceQe;
use app\admin\model\InsuranceQeRule;
use app\admin\model\InsuranceSection;
use app\admin\model\InsuranceAgent;
use app\admin\model\InsuranceConfig;
use app\admin\model\InsuranceReprule;
use app\admin\model\InsuranceReport;
use app\admin\model\InsuranceNotice;
use app\admin\model\InsuranceAliocr;
use app\admin\model\InsuranceAliocrLogs;
use app\admin\model\InsuranceUser;

use app\admin\service\insurance\PolicyService;

use app\admin\service\TriggerService;
use app\common\constants\MenuConstant;
use app\admin\service\annotation\ControllerAnnotation;
use app\admin\service\annotation\NodeAnnotation;
use app\common\controller\AdminController;
use app\Request;
use think\App;
use think\response\Json;
use app\common\utils\Crypt;
use think\facade\Env;

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use app\common\utils\CurrencyConverter;

#[ControllerAnnotation(title: '保单')]
class Policy extends AdminController
{
    protected array $sort = [
        'id'   => 'desc',
    ];

    protected array $allowModifyFields = [
        'is_billpay',
        'vv_tax',
    ];

    protected array $noExportFields = [
        'carowner',
        'files',
        'file_sy',
        'file_jq',
        'file_jc',
        'image_sy',
        'image_jq',
        'image_jc',
        'ocr_json_sy',
        'ocr_json_jq',
        'ocr_json_jc',
        'mine_data_sy',
        'mine_data_jq',
        'mine_data_jc',
        'status',
        'amount_me',
        'auth_id',
        'delete_time',
        'create_time',
        'update_time',
        'is_notice',
        'type_sy',
        'type_jq',
        'type_jc',
    ];

    protected static mixed  $i_config_model;
    protected static  $i_config;
    protected $service;


    // protected static mixed $model_ac;

    public function __construct(App $app, PolicyService $service)
    {
        parent::__construct($app);
        self::$model = InsurancePolicy::class;
        // self::$model_ac = InsurancePolicyAc::class;
        self::$i_config_model = InsuranceConfig::class;

        self::$i_config = self::$i_config_model::find(1);

        $this->service = $service;
        $car_type = $service->getCarTypeList();
        $this->assign('car_type', $car_type);
        $agent = InsuranceAgent::where('status', 1)->select()->toArray();
        $this->assign('agent', $agent);
        $this->assign('ocr_type', self::$i_config['settings']['ocr_type']);
    }

    #[NodeAnnotation(title: '列表', auth: true)]
    public function index(Request $request): Json|string
    {
        if ($request->isAjax()) {
            if (input('selectFields')) {
                return $this->selectList();
            }
            list($page, $limit, $where) = $this->buildTableParams();
            
            list($count, $list) = $this->service->getPageList($where, $page, $limit, $this->sort);

            $data  = [
                'code'  => 0,
                'msg'   => '',
                'count' => $count,
                'data'  => $list,
            ];
            return json($data);
        }
        return $this->fetch();
    }

    #[NodeAnnotation(title: '单个PDF转图片', auth: true)]
    public function pdf2ImgOne(Request $request): Json{
        $post   = $request->post();
        $pdf = $post['pdf'];
        if (empty($pdf)) {
            return json(['code' => 0, 'message' => '数据错误', 'data' => $pdf]);
        }
        $pdf = "." . $pdf;
        if (!is_file($pdf)) {
            return json(['code' => 0, 'message' => '文件不存在', 'data' => $pdf]);
        }
        $settings = self::$i_config['settings'];
        if ($settings['ocr_type'] == 0) {
            $image = $this->service->pdfToImage($pdf);
        } else if ($settings['ocr_type'] == 1) {
            $image = $this->service->pdfToImage1($pdf);
        }
        $data = [
            "image" => $image,
            'file'   => $pdf,
        ];
        return json(['code' => 1, 'message' => 'success', 'data' => $data]);
    }

    #[NodeAnnotation(title: 'OCR识别', auth: true)]
    public function ocrImg(): Json{
        $data = $this->service->ocr();
        if (count($data) == 0) {
            return json(['code' => 0, 'message' => '数据错误', 'data' => $data]);
        }
        return json(['code' => 1, 'message' => 'success', 'data' => $data]);
    }

    public function test(){
        // $list = $this->service->getList();
        // $image = $this->service->pdfToImage('./storage/20250807/jho1754545813yCaVwE1.pdf');
        // return json([$list, $image]);
        echo $_SERVER['DOCUMENT_ROOT'];exit;
        $parser = new Parser();
        $pdf = $parser->parseFile('./storage/20250807/jho1754545813yCaVwE1.pdf');
        $pages = $pdf->getPages()[0];
        $text = '';
        $text = $page->getText();
        return json($text);
        $res = $this->service->bdOcr();
        return json($res);
    }

    #[NodeAnnotation(title: '获取险种', auth: true)]
    public function getSaleType(){
        $res = [
            'code' => 1,
            'msg' => 'success',
            'data' => [
                ['id' => 1, 'title' => '个代'],
                ['id' => 2, 'title' => '业务员直销'],
                ['id' => 3, 'title' => '合作厂'],
            ],
            'url' => '',
            'wait' => 3,
        ];
        return json($res);
    }

    #[NodeAnnotation(title: '获取车辆类型', auth: true)]
    public function getCarTypeList(){
        $res = [
            'code' => 1,
            'msg' => 'success',
            'data' => $this->service->getCarTypeList(),
            'url' => '',
            'wait' => 3,
        ];
        return json($res);
    }

    #[NodeAnnotation(title: '添加', auth: true)]
    public function add(Request $request): string
    {
        if ($request->isPost()) {
            $post = $request->post();
            $cost_jq = $post['data']['cost_jq'] ?? 0;
            $bind_history_policy_id = $post['data']['bind_history_policy_id'] ?? 0;
            $is_history_single = $post['data']['is_history_single'] ?? 0;
            if ($bind_history_policy_id > 0) {
                $bind_history_policy = $this->model::where('id', $bind_history_policy_id)->find();
                if (empty($bind_history_policy)) {
                    $this->error('数据错误');
                }
            }
            $auth_id = session('admin')['id'];
            $data = $post['data']['data'];
            if (!is_array($data) || count($data) <= 0) {
                $this->error('数据错误');
            }
            try {
                // 投保人信息
                $userinfo = [];
                $batch_ident = '';
                $start_at = '';
                $types = [];
                // var_dump($data);
                foreach ($data as $k => $v) {
                    if (in_array($v['type'], $types)) { // 去除相同保险类型保单
                        unset($data[$k]);
                        continue;
                    }
                    // $data[$k]['image'] = '';
                    $types[] = $v['type'];
                    if (empty($batch_ident)) {
                        $batch_ident = $v['num'].$v['create_at'];
                    }
                    if (empty($userinfo['insurer'])) {
                        $userinfo['insurer'] = $v['insurer'] ?? '';
                    }
                    if (empty($userinfo['carno'])) {
                        $userinfo['carno'] = $v['carno'] ?? '';
                    }
                    if (empty($userinfo['idcard'])) {
                        $userinfo['idcard'] = $v['idcard'] ?? '';
                    }
                    if (empty($userinfo['mobile'])) {
                        $userinfo['mobile'] = $v['mobile'] ?? '';
                    }
                    $data[$k]['batch_ident'] = $batch_ident;
                    $data[$k]['auth_id'] = $auth_id;
                    if ($v['type'] == 1 && $is_history_single > 0) {
                        $start_at = $v['start_at'];
                        $data[$k]['is_history_single'] = $is_history_single;
                        $data[$k]['cost_jq'] = $cost_jq;
                        $data[$k]['history_policy_id'] = $history_policy_id;
                    }

                }
                if (count($types) == 1 && $types[0] == 2) {
                    $this->error('不能单独提交驾乘保单');
                }
                $user = InsuranceUser::where('insurer', $userinfo['insurer'])->where('carno', Crypt::encrypt($userinfo['carno']))->find();
                // 没有投保人数据新建 否则更新
                if (empty($user)) {
                    $save = InsuranceUser::create($userinfo)->policy()->saveAll($data);
                } else {
                    $history_policys = $user->policy()->where('status', 1)->where('end_at', '>', strtotime($start_at))->select();
                    if (count($history_policys) == 0) {
                        $save = $user->policy()->saveAll($data);
                    } else {
                        $batch_ident = $history_policys[0]['batch_ident'];
                        $d = [];
                        $save = false;
                        $types = [];
                        foreach ($history_policys as $k => $v) {
                            $types[] = $v['type'];
                        }
                        foreach ($data as $k => $v) {
                            $data[$k]['batch_ident'] = $batch_ident;
                            if (in_array($v['type'], $types)) { // 如果存在相同类型保单则去除
                                unset($data[$k]);
                            }
                        }
                        if (count($data) > 0) {
                            $save = $user->policy()->saveAll($data);
                        } else {
                            $save = false;
                        }
                    }
                }
                
            } catch (\Exception $e) {
                $this->error('保存失败'.$e->getMessage(), $post);
            }
            if ($save) {
                // TriggerService::updateMenu();
                $this->success('保存成功');
            }else {
                $this->error('保存失败');
            }
        }
        return $this->fetch();
    }

    #[NodeAnnotation(title: '编辑', auth: true)]
    public function edit(Request $request, $id = 0): string
    {
        $row = self::$model::find($id);
        empty($row) && $this->error('数据不存在');
        if ($request->isPost()) {
            $post = $request->post();
            $post['auth_id'] = session('admin')['id'];
            if ($row['is_billpay']) {
                $this->error('已结费不能修改');
            }
            try {
                $save = $row->save($post);
            }catch (\Exception $e) {
                $this->error('保存失败');
            }
            if ($save) {
                // TriggerService::updateMenu();
                $this->success('保存成功');
            }else {
                $this->error('保存失败');
            }
        }
        $this->assign([
            'id'          => $id,
            'row'         => $row,
        ]);
        return $this->fetch();
    }

    #[NodeAnnotation(title: '追加', auth: true)]
    public function supplement(Request $request, $id = 0): string
    {
        $id = $id ?: $request->param('data.id');
        $row = self::$model::with('user')->with('report')->find($id);
        empty($row) && $this->error('数据不存在');
        if ($request->isPost()) {
            $m_types = self::$model::where('batch_ident', $row['batch_ident'])->where('status', 1)->field('type, id')->select() ?: [];
            $post = $request->post();
            $auth_id = session('admin')['id'];
            $data = $post['data']['data'];
            if (!is_array($data) || count($data) <= 0) {
                $this->error('数据错误');
            }

            try {
                $batch_ident = $row['batch_ident'];
                $types = [$row['type']];
                foreach ($m_types as $v) {
                    $types[] = $v['type'];
                }
                foreach ($data as $k => $v) {
                    if (in_array($v['type'], $types)) { // 去除相同保险类型保单
                        unset($data[$k]);
                        continue;
                    }
                    $types[] = $v['type'];
                    $data[$k]['batch_ident'] = $batch_ident;
                    $data[$k]['auth_id'] = $auth_id;
                    $data[$k]['agent'] = $row['agent'];
                    $data[$k]['user_id'] = $row['user_id'];
                }
                if (count($data) > 0) {
                    $save = self::$model::saveAll($data);
                } else {
                    $save = false;
                }
                
            } catch (\Exception $e) {
                $this->error('保存失败', $post);
            }
            if ($save) {
                // TriggerService::updateMenu();
                $this->success('保存成功');
            }else {
                $this->error('保存失败');
            }
        }
        $this->assign([
            'id'          => $id,
            'row'         => $row,
        ]);
        return $this->fetch();
    }

    #[NodeAnnotation(title: '查询历史单交', auth: true)]
    public function gethistoryList(Request $request): Json{
        if ($request->isPost()) {
            $post = $request->post();
            $start_at = strtotime($post['start_at']);
            $user = InsuranceUser::where('insurer', $request->param('insurer'))
                                ->where('carno', $request->param('carno'))
                                ->find();
            if (!$user) {
                return json(['code' => 0, 'msg' => '没有找到该用户', 'data' => [], 'url' => '', 'wait' => 1]);
            }
            $subQuery = $user->policy()
                ->field('id')
                ->group('batch_ident')
                ->having('count(*) = 1')
                ->buildSql();
            $res = $user->policy()
                ->field('id, num, create_at, end_at, type')
                ->where('status', 1)
                ->where('type', 0)
                ->where('end_at', '>', strtotime($start_at))
                ->where("id in $subQuery")
                ->order('end_at desc')
                ->find() ?: [];
            return json(['code' => 1, 'msg' => '成功', 'data' => $res, 'url' => '', 'wait' => 1]);
        }
    }

    #[NodeAnnotation(title: '删除', auth: true)]
    public function delete(Request $request): void
    {
        $this->checkPostRequest();
        $id  = $request->param('id');
        $row = self::$model::whereIn('id', $id)->select();
        empty($row) && $this->error('数据不存在');
        try {
            $save = $row->update(['status' => 0, 'delete_time' => time()]);
        }catch (\Exception $e) {
            $this->error('删除失败');
        }
        if ($save) {
            // TriggerService::updateMenu();
            $this->success('删除成功');
        }else {
            $this->error('删除失败');
        }
    }

    #[NodeAnnotation(title: '结费', auth: true)]
    public function billpay(Request $request): Json{
        if ($request->isPost()) {
            $post = $request->post();
            $ids = $post['ids'];
            
            $is_billpay = !empty($post['no']) ? 0 : 1;
            try {
                // 默认结费
                $res = self::$model::whereIn('id', $ids)->update(['is_billpay' => $is_billpay]);
            }catch (\Exception $e) {
                return json(['code' => 0, 'msg' => '失败', 'data' => [], 'url' => '', 'wait' => 3]);
            }
            if ($res) {
                return json(['code' => 1, 'msg' => '成功', 'data' => [], 'url' => '', 'wait' => 3]);
            } else {
                return json(['code' => 0, 'msg' => '失败', 'data' => $ids, 'url' => '', 'wait' => 3]);
            }
        }
    }

    #[NodeAnnotation(title: '匹配费用', auth: true)]
    public function setQe(Request $request): Json{
        if ($request->isPost()) {
            $config = InsuranceConfig::find(1);
            $ids = $request->post('ids');
            $res = $this->service->setQe($ids);
            if ($res['code'] == 1) {
                return json(['code' => 1, 'msg' => $res['msg'], 'data' => [], 'url' => '', 'wait' => 3]);
            } else {
                return json(['code' => 0, 'msg' => $res['msg'], 'data' => [], 'url' => '', 'wait' => 3]);
            }
        }
    }

    #[NodeAnnotation(title: '获取通知', auth: true)]
    public function getNotice(){
        $start = strtotime(date('Y-m-d'));
        $end = strtotime(date('Y-m-d', strtotime('+30 day')));
        $record = self::$model::where('is_notice', '<>', 1)
                        ->where('status', 1)
                        ->where(function($query) use($start, $end){
                            $query->where('end_at', 'between', [$start, $end]);
                        })
                        ->find();
        if (empty($record)) {
            return json(['code' => 0, 'msg' => '暂无数据']);
        }
        $date = date('Y-m-d');
        $today = strtotime($date);
        $notice = InsuranceNotice::where('notice_time', $today)->find();
        $data = [
            'notice_time' => $today,
            'notice_title' => '续保通知',
            'notice_content' => '续保列表',
        ];
        if (empty($notice)) {
            $notice =InsuranceNotice::create($data);
        }
        if ($notice['is_notice'] == 0) {
            return json(['code' => 0, 'msg' => '暂无通知']);
        }
        return json(['code' => 1, 'msg' => '续保通知', 'data' => $notice, 'date' => $date]);
    }

    #[NodeAnnotation(title: '设置通知', auth: true)]
    public function setNotice(){
        $data = $this->request->post();
        $notice = InsuranceNotice::where('id', $data['id'])->find();
        if (empty($notice)) {
            return json(['code' => 0, 'msg' => '数据不存在']);
        }
        $notice->is_notice = 0;
        $notice->save();
        return json(['code' => 1, 'msg' => '操作成功']);
    }

    #[NodeAnnotation(title: '续保列表', auth: true)]
    public function renewals(Request $request): Json|string{
        return $this->fetch();
    }

    #[NodeAnnotation(title: '标记已通知', auth: true)]
    public function setPolicyNotice(Request $request): Json{
        if ($request->post()){
            $data = $request->post();
            $res = self::$model::where('id', 'in', $data['ids'])->update(['is_notice' => 1]);
            if (!$res) {
                return json(['code' => 0, 'msg' => '操作成功']);
            }
            return json(['code' => 1, 'msg' => '操作成功']);
        }
    }

    #[NodeAnnotation(title: '批量修改', auth: true)]
    public function batchmodify(Request $request): Json{
        if ($request->post()){
            $data = $request->post();
            if (count($data['ids']) == 0) {
                return json(['code' => 0, 'msg' => '请选择数据']);
            }
            if (empty($data['car_type']) && empty($data['agent'])
                && !is_numeric($data['is_transfer_owner']) && !is_numeric($data['is_renewal'])) {
                return json(['code' => 0, 'msg' => '修改为空']);
            }
            $d = [];
            if (!empty($data['car_type'])) {
                $d['car_type'] = $data['car_type'];
            }
            if (!empty($data['agent'])) {
                $d['agent'] = $data['agent'];
            }
            if (is_numeric($data['is_transfer_owner'])) {
                $d['is_transfer_owner'] = $data['is_transfer_owner'];
            }
            if (is_numeric($data['is_renewal'])) {
                $d['is_renewal'] = $data['is_renewal'];
            }
            $save = self::$model::whereIn('id', $data['ids'])->update($d);
            if (!$save) {
                return json(['code' => 0, 'msg' => '操作失败']);
            }
            return json(['code' => 1, 'msg' => '操作成功']);
        }
        return json(['code' => 0, 'msg' => '操作失败']);
    }

}
